<?php

namespace App\Http\Controllers\Chat;

use App\Http\Controllers\queue\Consumer;
use App\Http\Controllers\Queue\PriorityTree;
use App\Http\Requests\System\Employee;
use App\Models\Chat\ChatEmployDepartment;
use App\Models\Chat\ChatEmployeeMessage;
use App\Models\Chat\ChatEmployUsers;
use App\Models\Chat\ChatGroup;
use App\Models\Chat\ChatGroupMessage;
use App\Models\Chat\ChatUsers;
use App\Models\SystemManagement\Department;
use App\Models\SystemManagement\DepartmentEmployee;
use App\Workerman\Events;
use Egulias\EmailValidator\Exception\AtextAfterCFWS;
use GatewayWorker\Lib\Gateway;
use http\Env\Response;
use Illuminate\Auth\Access\Gate;
use Illuminate\Http\Request;
use App\Models\CarModels\CarCity;
use App\Http\Controllers\Controller;
use Illuminate\Database\QueryException;
use App\Traits\UploadTrait;
use Illuminate\Support\Facades\DB;
use Validator;

/**
 * @group 手机端->消息 聊天群组的查看 添加 群组踢人 群组解散
 *
 * 采用 restful api
 *
 * Body Parameters 表示请求的所需要的参数
 *
 * Query Parameters 表示返回参数的名称
 */
class ChatGroupController extends Controller
{

    static function getSql($sql, $employeeId)
    {
        if ($sql === 'employee')
            return "select distinct `hw_chat_employ_users`.`chat_group_id` from `hw_employees` inner join `hw_chat_employ_users` on `hw_employees`.`id` = `hw_chat_employ_users`.`employee_id` where `hw_chat_employ_users`.`employee_id`={$employeeId}";
        if ($sql === 'department')
            return "select `hw_chat_employ_department`.`chat_group_id` from `hw_chat_employ_department` INNER JOIN `hw_departments` on `hw_chat_employ_department`.`employ_department_id` = `hw_departments`.`id` INNER JOIN `hw_employees` on `hw_employees`.`department_id` = `hw_departments`.`id` where `hw_employees`.id={$employeeId}";

        return false;
    }
    //选出用户的所有聊天群
    static function getEmployeeGroup($employeeId)
    {
        //1. 通过用户所属的群聊来获取聊天群 2. 通过用户所属的部门 如果部门在里面也要遍历出来
        try {
            $employeeChat = DB::select(self::getSql('employee', $employeeId));
            $DepartmentChat = DB::select(self::getSql('department', $employeeId));
        } catch (\Exception $e) {
            var_dump($e->getMessage());
            return [];
        }
        $ids = array_merge($employeeChat, $DepartmentChat);
        $ids = array_map(function ($item) {
            return $item->chat_group_id;
        }, $ids);
        $ids = array_unique($ids);
        return $ids;
    }

    /**
     * 查看所有群聊群的信息以及群聊群下面的群聊部门和群聊人员
     *
     * @bodyParam employee_id int optional 过滤某个员工的所有聊天群组 传递员工表的id 员工信息接口 api/system/employee 使用该接口的id字段
     * @queryParam name 车辆所属城市的名称
     */
    public function index(Request $request)
    {
        $e = genValidate();
        $validator = Validator::make($request->all(), $e);
        if ($validator->fails()) {
            return response()->json(encodeMsg($validator->errors()->messages(), 400), 400);
        }
        $user_id = $request->user_id;
        //用户id号来筛选
        if ($user_id) {
            $employee = ChatEmployeeMessage::with('sender')->where('receiver_id', $user_id)->distinct()->get(['sender_id'])->toArray();
            $employee = array_map(function($item){
                $item['type'] = 'employee';
                return $item;
            },$employee);
            $groups = ChatGroup::with('users')->with('departments')->whereIn('id', self::getEmployeeGroup($user_id))->orderBy('updated_at','desc')->get()->toArray();
            $groupsId = [];
            foreach ($groups as $group)
            {
                array_push($groupsId,$group['id']);
            }
            $owners = ChatGroup::where('employee_id',$user_id)->get()->toArray();
            foreach ($owners as $owner){
                if(!in_array($owner['id'],$groupsId))
                    array_push($groupsId,$owner['id']);
            }
            $chats = ChatGroup::whereIn('id',$groupsId)->get()->toArray();
            $chats = array_map(function($item){
                $item['type'] = 'group';
                return $item;
            },$chats);
            return response()->json(['group' => $chats, 'employee' => $employee]);
        }
        return response()->json(ChatGroup::with('users')->with('departments')->get());
    }


    /**
     * 查看所有群聊群的信息以及群聊群下面的群聊部门和群聊人员
     *
     * @bodyParam employee_id int optional 过滤某个员工的所有聊天群组 传递员工表的id 员工信息接口 api/system/employee 使用该接口的id字段
     * @queryParam name 车辆所属城市的名称
     */
    public function index1(Request $request)
    {
        $e = genValidate();
        $validator = Validator::make($request->all(), $e);
        if ($validator->fails()) {
            return response()->json(encodeMsg($validator->errors()->messages(), 400), 400);
        }
        $user_id = $request->user_id;
        //用户id号来筛选
        if ($user_id) {
            $total = [];
            $employees = ChatUsers::where(['receiver'=>$user_id])->orderby('updated_at')->get()->toArray();

            $groups = ChatGroup::with('departments')->whereIn('id', self::getEmployeeGroup($user_id))->orderBy('updated_at','desc')->get()->toArray();
            $groupsId = [];
            foreach ($groups as $group)
            {
                array_push($groupsId,$group['id']);
            }
            //$groupMessage = ChatGroupMessage::whereIn('chat_id',$groupsId)->get()->toArray();



            $chats = ChatGroup::whereIn('id',$groupsId)->get()->toArray();
            $data = (array_merge($chats,$employees));
            (array_column($data, 'updated'));
            dd($data);
            return response()->json(['group' => $chats, 'employee' => $employee]);
        }
        return response()->json(ChatGroup::with('users')->with('departments')->get());
    }

    /**
     *
     * 手机端->消息->选择联系人-组织
     *
     * 注意点,这里聊天添加可以同时的把群组和个人都加在一起聊天,所以需要传递两个id的数组过来
     * @bodyParam department_ids string optional 所要建立群聊的部门id号 多个部门间聊天用数组传递 示例 [1,2,3,4,5]
     * @bodyParam user_ids string optional 所要建立群聊的用户的id号多个用户使用数组传递 [1,2,3,4,5]
     * @bodyParam name string required 聊天群的名称 这里不能重复
     *
     */
    public function store(Request $request)
    {
        $e = genValidate();
        $validator = Validator::make($request->all(), $e);
        if ($validator->fails()) {
            return response()->json(encodeMsg($validator->errors()->messages(), 400), 400);
        }
        $user_id = $request->user_id;
        $creator = $user_id;//这个只是测试用的
        $departmentRecipients = $request->input('department_ids', null);
        $userRecipients = $request->input('user_ids', null);
        if($userRecipients == null){
            $userRecipients = "[$user_id]";
        }else{
            $userRecipients =substr($userRecipients,0,strlen($userRecipients) - 1);
            $userRecipients .= ",$user_id]";
        }

        if (!($departmentRecipients || $userRecipients))
            return response()->json(encodeMsg(["message" => "部门和用户id不能同时为空"], 404), 404);

        $name = $request->get('name');
        Gateway::$registerAddress = '0.0.0.0:51235';
        DB::beginTransaction();
        try {
            $chat = ChatGroup::create(['name' => $name, 'employee_id' => $creator]);

        } catch (\Exception $e) {
            return response()->json(encodeMsg(["message" => $e->getMessage()], 405), 405);
        }
        if ($departmentRecipients) {
            $departmentRecipientsArr = (array)json_decode($departmentRecipients);
            if ($departmentRecipientsArr === []) {
                return response()->json(encodeMsg(["message" => '部门id号格式有误,无法创建部门群聊'], 406), 406);

            }
            $departmentRecipientsArr = array_unique($departmentRecipientsArr);
            try {

                foreach ($departmentRecipientsArr as $recipient) {
                    ChatEmployDepartment::create(['chat_group_id' => $chat->id, 'employ_department_id' => $recipient]);
                }
                $departments = ChatEmployDepartment::with('department')->whereIn('id',$departmentRecipientsArr)->get()->toArray();
                $userIds = [];
                foreach ($departments as $department){
                    foreach ($department['department']['users'] as $user){
                        if(in_array($user['id'],$userIds))
                            continue;
                        array_push($userIds,$user['id']);
                    }
                }
                //遍历所有用户id 把这些用户加入到聊天室中
                foreach ($userIds as $userId){
                    $chatClientIds = Gateway::getClientIdByUid(Events::chatEmployeeIdToWSEmployeeId($userId));
                    foreach ($chatClientIds as $chatClientId){
                        Gateway::joinGroup($chatClientId,Events::chatGroupIdToWSGroupId($chat->id));
                    }
                }

            } catch (\Exception $e) {
                DB::rollBack();
                return response()->json(encodeMsg(["message" => $e->getMessage()], 501), 501);
            }
        }
        if ($userRecipients) {
            $userRecipientsArr = (array)json_decode($userRecipients);
            if ($userRecipientsArr === []) {
                return response()->json(encodeMsg(["message" => '员工id号格式有误,无法创建员工群聊'], 407), 407);

            }
            $userRecipientsArr = array_unique($userRecipientsArr);
            try {
                foreach ($userRecipientsArr as $recipient) {
                    ChatEmployUsers::create(['chat_group_id' => $chat->id, 'employee_id' => $recipient]);
                }

                $employees = ChatEmployUsers::whereIn('id',$userRecipientsArr)->get()->toArray();


                foreach ($employees as $employee){
                    $chatClientIds = Gateway::getClientIdByUid(Events::chatEmployeeIdToWSEmployeeId($employee['employee_id']));
                    foreach ($chatClientIds as $chatClientId){
                        Gateway::joinGroup($chatClientId,Events::chatGroupIdToWSGroupId($chat->id));
                    }
                }
            } catch (\Exception $e) {
                DB::rollBack();
                return response()->json(encodeMsg(["message" => $e->getMessage()], 502), 502);
            }
        }
        DB::commit();
        return response()->json(encodeMsg(["message" => $chat], 201), 201);
    }

    /**
     * 车辆所属城市信息显示(单个信息显示)
     *
     * @queryParam  name 车辆所属城市的名称
     *
     */
    public function show($pk)
    {
        $data = \App\Models\CarModels\CarCity::with('areas')->find($pk);
        if ($data == []) {
            return response()->json(encodeMsg(["message" => "没有该车辆所属城市信息"], 404), 404);
        } else {
            return response()->json(encodeMsg($data, 200), 200);
        }
    }

    /**
     * 修改聊天室信息 主要管理员添加或者删除聊天成员
     *
     * @bodyParam action int required 在群聊中删除部门 1 在群聊中添加部门 2 在群聊中删除个人 3 在群聊中添加个人 4
     *
     * @queryParam ids string required 被执行的对象主键 [1,2,3] 可以同时添加多个和删除多个
     *
     */
    public function update(Request $request, $pk)
    {
        $e = genValidate();
        $validator = Validator::make($request->all(), $e);
        if ($validator->fails()) {
            return response()->json(encodeMsg($validator->errors()->messages(), 400), 400);
        }
        $action = $request->get('action');
        $ids = $request->get('ids');
        $ids = (array)json_decode($ids);

        //通过这个方式可以和workerman建立ipc
        Gateway::$registerAddress = '0.0.0.0:51235';
        $chatUid = Events::$employeeBase + $pk;
        $chatGroupId = Events::$groupIdBase + $pk;
        $idCache = [];
        if ($action == 1) {
            //剔除部门的逻辑 1. 数据库中遍历出该部门的所有的员工,把他们一一剔除群聊 2. 删除部门的聊天室的关联
            //获取到要执行操作的部门
            $departments = Department::whereIn('id', $ids)->with('users')->get()->toArray();
            //把所有的部门id提取出来
            $departmentIds = array_map(function ($item){return $item['id'];},$departments);
            $chatDepartments = ChatEmployDepartment::where(["chat_group_id" => $pk])->whereIn('employ_department_id', $departmentIds);
            $chatDepartments->delete();
            foreach ($departments as $department) {
                foreach ($department['users'] as $user) {
                    //避免用户被重复执行操作
                    if(in_array($user['id'],$idCache))
                        continue;
                    $userChatId = Events::$employeeBase + $user['id'];
                    //通过userId获取到用户当前的聊天id号
                    $chatClientIds = Gateway::getClientIdByUid($userChatId);
                    foreach ($chatClientIds as $chatClientId) {
                        Gateway::leaveGroup($chatClientId, Events::chatGroupIdToWSGroupId($chatGroupId));
                    }
                    array_push($idCache,$idCache);
                }
            }
        }elseif($action == 2)
        {
            try {
                $departments = Department::whereIn('id', $ids)->with('users')->get()->toArray();

                $departmentIds = array_map(function ($item) {
                    return $item['id'];
                }, $departments);
                $insertData = array_map(function ($item) use ($pk) {
                    return ['employ_department_id' => $item, 'chat_group_id' => $pk];
                }, $departmentIds);
                ChatEmployDepartment::insert($insertData);
                //获取添加部门的所有用户id
                $userIds = [];
                foreach ($departments as $department){
                    foreach ($department['users'] as $user){
                        if(in_array($user['id'],$userIds))
                            continue;
                        array_push($userIds,$user['id']);
                    }
                }
                //遍历所有用户id 把这些用户加入到聊天室中
                foreach ($userIds as $userId){
                    $chatClientIds = Gateway::getClientIdByUid(Events::chatEmployeeIdToWSEmployeeId($userId));
                    foreach ($chatClientIds as $chatClientId){
                        Gateway::joinGroup($chatClientId,Events::chatGroupIdToWSGroupId($pk));
                    }
                }
            }catch (\Exception $e){
                $code = $e->getCode();
                if($code == 23000){
                    return response('部门重复 不能添加');
                }
                return response('其他错误 不能添加');
            }

        }elseif($action == 3){
            $employees = ChatEmployUsers::whereIn('employee_id',$ids)->where(['chat_group_id'=>$pk])->get()->toArray();
            $employeeIds = array_map(function ($item){return $item['employee_id'];},$employees);
            //获取这些用户的clientid 把这些用户剔除聊天室并且删除数据库中的记录
            ChatEmployUsers::whereIn('employee_id',$ids)->where(['chat_group_id'=>$pk])->delete();
            foreach ($employeeIds as $employeeId){
                $chatClientIds = Gateway::getClientIdByUid(Events::chatEmployeeIdToWSEmployeeId($employeeId));
                foreach ($chatClientIds as $chatClientId){
                    Gateway::leaveGroup($chatClientId,Events::chatGroupIdToWSGroupId($pk));
                }
            }
        }elseif($action == 4){
            //找出所有合法用户
            $employees = \App\Models\SystemManagement\Employee::whereIn('id',$ids)->get()->toArray();
            //把这些用户添加到数据库中
            $insertData = array_map(function($item) use ($pk){return ['employee_id'=>$item['id'],'chat_group_id'=>$pk];},$employees);
            try {
                //添加到数据库中
                ChatEmployUsers::insert($insertData);
                //把这些人加入到聊天频道
                foreach ($employees as $employee){
                    $chatClientIds = Gateway::getClientIdByUid(Events::chatEmployeeIdToWSEmployeeId($employee['id']));
                    foreach ($chatClientIds as $chatClientId){
                        Gateway::joinGroup($chatClientId,Events::chatGroupIdToWSGroupId($pk));
                    }
                }
            }catch (\Exception $e){
                $code = $e->getCode();
                if($code == 23000){
                    return response('聊天人重复 不能添加');
                }
                return response('其他错误 不能添加');
            }
        }
        return response()->json('success');

    }

    /**
     * 车辆所属城市信息删除
     */

    public function destroy($pk)
    {
        $data = \App\Models\CarModels\CarCity::find($pk);
        if ($data == []) {
            return response()->json(encodeMsg(["message" => "没有该车辆所属城市信息"], 404), 404);
        }
        $data->delete();
        return response()->json(encodeMsg(["message" => "删除成功"], 204), 200);
    }
}
